/**
 * Copyright (c) 2019-2029, wwww.kiwipeach.cn (liuburu@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package cn.kiwipeach.blog.service.impl;

import cn.kiwipeach.blog.base.AjaxResponse;
import cn.kiwipeach.blog.database.domain.ArchiveBlogTimelineVO;
import cn.kiwipeach.blog.database.domain.BlogInfoDetailVO;
import cn.kiwipeach.blog.database.domain.BlogInfoVO;
import cn.kiwipeach.blog.database.domain.BlogNextPreviousVO;
import cn.kiwipeach.blog.database.generator.domain.Blog;
import cn.kiwipeach.blog.database.mapper.BlogArchiveMapper;
import cn.kiwipeach.blog.database.mapper.CustomBlogMapper;
import cn.kiwipeach.blog.database.mapper.CustomBlogTagMapper;
import cn.kiwipeach.blog.service.IBlogService;
import cn.kiwipeach.blog.service.adapter.AbstractBlogService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 博客 服务实现类
 *
 * @author kiwipeach
 * @since 1.0
 */
@Service
public class AbstractBlogServiceImpl extends AbstractBlogService implements IBlogService {

    @Autowired
    org.springframework.cache.CacheManager cacheManager;

    @Autowired
    private CustomBlogMapper customBlogMapper;

    @Autowired
    private CustomBlogTagMapper customBlogTagMapper;

    @Autowired
    private BlogArchiveMapper blogArchiveMapper;

    @Override
    public AjaxResponse<IPage<BlogInfoVO>> recommendPageQuery(IPage<BlogInfoVO> page) {
        List<BlogInfoVO> blogInfoVos = customBlogMapper.selectRecommendByPage(page);
        page.setRecords(blogInfoVos);
        return AjaxResponse.success(page);
    }

    @Override
    public AjaxResponse<IPage<BlogInfoVO>> pageQuery(IPage<BlogInfoVO> page, String categoryId, String tagId) {
        List<BlogInfoVO> blogInfoVos = customBlogMapper.selectByPage(page, categoryId, tagId);
        page.setRecords(blogInfoVos);
        return AjaxResponse.success(page);
    }

    @Override
    public AjaxResponse<BlogInfoDetailVO> queryById(String blogId) {
        BlogInfoDetailVO blogInfoVO = customBlogMapper.selectBlog(blogId);
        //dealTagsName(blogInfoVO);
        BlogNextPreviousVO nextBlog = customBlogMapper.selectNextBlog(new Page<>(2, 1), blogId);
        // 处理最后一篇博客下一篇问题
        if (nextBlog == null) {
            QueryWrapper<Blog> queryWrapper = new QueryWrapper<Blog>().eq("top", "1");
            Blog blog = customBlogMapper.selectOne(queryWrapper);
            nextBlog = transfer2BlogInfoVO(blog);
        }
        BlogNextPreviousVO previousBlog = customBlogMapper.selectPreviousBlog(new Page<>(0, 1), blogId);
        // 处理第一篇博客上一篇问题
        if (previousBlog == null) {
            QueryWrapper<Blog> queryWrapper = new QueryWrapper<Blog>().eq("top", "1");
            Blog blog = customBlogMapper.selectOne(queryWrapper);
            nextBlog = transfer2BlogInfoVO(blog);
        }
        blogInfoVO.setNextBlog(nextBlog);
        blogInfoVO.setPreviousBlog(previousBlog);
        return AjaxResponse.success(blogInfoVO);
    }

    /**
     * 数据类型转换
     *
     * @param blog 博客类型
     * @return 返回博客上一条或者下一条信息
     */
    private BlogNextPreviousVO transfer2BlogInfoVO(Blog blog) {
        return new BlogNextPreviousVO().setId(blog.getId()).setTitle(blog.getTitle());
    }

    @Override
    public AjaxResponse<IPage<ArchiveBlogTimelineVO>> archiveBlogQuery(IPage<ArchiveBlogTimelineVO> page, String pattern) {
        List<ArchiveBlogTimelineVO> archiveBlogTimelineVos = queryArchiveBlogByPattern(page, pattern);
        page.setRecords(archiveBlogTimelineVos);
        return AjaxResponse.success(page);
    }

    /**
     * 将前端传过来的日期类型转换成MySql本地语法
     *
     * @param pattern 前端日期
     * @return 返回mysql日期表示
     */
    private List<ArchiveBlogTimelineVO> queryArchiveBlogByPattern(IPage<ArchiveBlogTimelineVO> page, String pattern) {
        String yyyy = "yyyy";
        String yyyyq = "yyyyQ";
        String yyyymm = "yyyyMM";
        if (yyyy.equals(pattern)) {
            return blogArchiveMapper.selectArchiveBlogByYear(page);
        } else if (yyyyq.equals(pattern)) {
            return blogArchiveMapper.selectArchiveBlogByYearQuarter(page);
        } else if (yyyymm.equals(pattern)) {
            return blogArchiveMapper.selectArchiveBlogByYearMonth(page);
        } else {
            throw new IllegalArgumentException("非法参数异常:" + pattern);
        }
    }

    @Override
    public AjaxResponse<Boolean> createBlogAgree(String blogId, String sessionId) {
        String cacheKey = String.format("blogid_%s_sessionid_%s", blogId, sessionId);
        Cache agreeDetailCache = cacheManager.getCache("BLOG_START_COUNT");
        Cache.ValueWrapper valueWrapper = agreeDetailCache.get(cacheKey);
        //如果缓存中存在点赞数据，则不允许重复点赞
        if (valueWrapper == null) {
            Integer integer = customBlogMapper.updateBlogStarCount(blogId);
            if (integer > 0) {
                agreeDetailCache.put(cacheKey, integer);
                return AjaxResponse.success(true);
            } else {
                return AjaxResponse.fail("-BLOG_STAR_001", "博客点赞失败");
            }
        } else {
            return AjaxResponse.fail("-BLOG_STAR_001", "您近期点过赞，无须频繁点赞.");
        }
    }

    @Override
    public AjaxResponse<Boolean> uploadBlog(MultipartFile multipartFile) {
        return null;
    }

}
